{
GHashTable *cell_info;
- GtkBorder border;
+ GtkBorder cell_border;
};
/* Keep the paramspec pool internal, no need to deliver notifications
enum {
PROP_0,
- PROP_MARGIN_LEFT,
- PROP_MARGIN_RIGHT,
- PROP_MARGIN_TOP,
- PROP_MARGIN_BOTTOM
+ PROP_CELL_MARGIN_LEFT,
+ PROP_CELL_MARGIN_RIGHT,
+ PROP_CELL_MARGIN_TOP,
+ PROP_CELL_MARGIN_BOTTOM
};
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkCellArea, gtk_cell_area, G_TYPE_INITIALLY_UNOWNED,
NULL,
(GDestroyNotify)cell_info_free);
- priv->border.left = 0;
- priv->border.right = 0;
- priv->border.top = 0;
- priv->border.bottom = 0;
+ priv->cell_border.left = 0;
+ priv->cell_border.right = 0;
+ priv->cell_border.top = 0;
+ priv->cell_border.bottom = 0;
}
static void
/* Properties */
g_object_class_install_property (object_class,
- PROP_MARGIN_LEFT,
- g_param_spec_int ("margin-left",
- P_("Margin on Left"),
- P_("Pixels of extra space on the left side"),
- 0,
- G_MAXINT16,
- 0,
- GTK_PARAM_READWRITE));
+ PROP_CELL_MARGIN_LEFT,
+ g_param_spec_int
+ ("cell-margin-left",
+ P_("Margin on Left"),
+ P_("Pixels of extra space on the left side of each cell"),
+ 0,
+ G_MAXINT16,
+ 0,
+ GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
- PROP_MARGIN_RIGHT,
- g_param_spec_int ("margin-right",
- P_("Margin on Right"),
- P_("Pixels of extra space on the right side"),
- 0,
- G_MAXINT16,
- 0,
- GTK_PARAM_READWRITE));
-
+ PROP_CELL_MARGIN_RIGHT,
+ g_param_spec_int
+ ("cell-margin-right",
+ P_("Margin on Right"),
+ P_("Pixels of extra space on the right side of each cell"),
+ 0,
+ G_MAXINT16,
+ 0,
+ GTK_PARAM_READWRITE));
+
g_object_class_install_property (object_class,
- PROP_MARGIN_TOP,
- g_param_spec_int ("margin-top",
- P_("Margin on Top"),
- P_("Pixels of extra space on the top side"),
- 0,
- G_MAXINT16,
- 0,
- GTK_PARAM_READWRITE));
+ PROP_CELL_MARGIN_TOP,
+ g_param_spec_int
+ ("cell-margin-top",
+ P_("Margin on Top"),
+ P_("Pixels of extra space on the top side of each cell"),
+ 0,
+ G_MAXINT16,
+ 0,
+ GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
- PROP_MARGIN_BOTTOM,
- g_param_spec_int ("margin-bottom",
- P_("Margin on Bottom"),
- P_("Pixels of extra space on the bottom side"),
- 0,
- G_MAXINT16,
- 0,
- GTK_PARAM_READWRITE));
+ PROP_CELL_MARGIN_BOTTOM,
+ g_param_spec_int
+ ("cell-margin-bottom",
+ P_("Margin on Bottom"),
+ P_("Pixels of extra space on the bottom side of each cell"),
+ 0,
+ G_MAXINT16,
+ 0,
+ GTK_PARAM_READWRITE));
/* Pool for Cell Properties */
if (!cell_property_pool)
switch (prop_id)
{
- case PROP_MARGIN_LEFT:
- gtk_cell_area_set_margin_left (area, g_value_get_int (value));
+ case PROP_CELL_MARGIN_LEFT:
+ gtk_cell_area_set_cell_margin_left (area, g_value_get_int (value));
break;
- case PROP_MARGIN_RIGHT:
- gtk_cell_area_set_margin_right (area, g_value_get_int (value));
+ case PROP_CELL_MARGIN_RIGHT:
+ gtk_cell_area_set_cell_margin_right (area, g_value_get_int (value));
break;
- case PROP_MARGIN_TOP:
- gtk_cell_area_set_margin_top (area, g_value_get_int (value));
+ case PROP_CELL_MARGIN_TOP:
+ gtk_cell_area_set_cell_margin_top (area, g_value_get_int (value));
break;
- case PROP_MARGIN_BOTTOM:
- gtk_cell_area_set_margin_bottom (area, g_value_get_int (value));
+ case PROP_CELL_MARGIN_BOTTOM:
+ gtk_cell_area_set_cell_margin_bottom (area, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
switch (prop_id)
{
- case PROP_MARGIN_LEFT:
- g_value_set_int (value, priv->border.left);
+ case PROP_CELL_MARGIN_LEFT:
+ g_value_set_int (value, priv->cell_border.left);
break;
- case PROP_MARGIN_RIGHT:
- g_value_set_int (value, priv->border.right);
+ case PROP_CELL_MARGIN_RIGHT:
+ g_value_set_int (value, priv->cell_border.right);
break;
- case PROP_MARGIN_TOP:
- g_value_set_int (value, priv->border.top);
+ case PROP_CELL_MARGIN_TOP:
+ g_value_set_int (value, priv->cell_border.top);
break;
- case PROP_MARGIN_BOTTOM:
- g_value_set_int (value, priv->border.bottom);
+ case PROP_CELL_MARGIN_BOTTOM:
+ g_value_set_int (value, priv->cell_border.bottom);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
/* Margins */
gint
-gtk_cell_area_get_margin_left (GtkCellArea *area)
+gtk_cell_area_get_cell_margin_left (GtkCellArea *area)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
- return area->priv->border.left;
+ return area->priv->cell_border.left;
}
void
-gtk_cell_area_set_margin_left (GtkCellArea *area,
- gint margin)
+gtk_cell_area_set_cell_margin_left (GtkCellArea *area,
+ gint margin)
{
GtkCellAreaPrivate *priv;
priv = area->priv;
- if (priv->border.left != margin)
+ if (priv->cell_border.left != margin)
{
- priv->border.left = margin;
+ priv->cell_border.left = margin;
g_object_notify (G_OBJECT (area), "margin-left");
}
}
gint
-gtk_cell_area_get_margin_right (GtkCellArea *area)
+gtk_cell_area_get_cell_margin_right (GtkCellArea *area)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
- return area->priv->border.right;
+ return area->priv->cell_border.right;
}
void
-gtk_cell_area_set_margin_right (GtkCellArea *area,
- gint margin)
+gtk_cell_area_set_cell_margin_right (GtkCellArea *area,
+ gint margin)
{
GtkCellAreaPrivate *priv;
priv = area->priv;
- if (priv->border.right != margin)
+ if (priv->cell_border.right != margin)
{
- priv->border.right = margin;
+ priv->cell_border.right = margin;
g_object_notify (G_OBJECT (area), "margin-right");
}
}
gint
-gtk_cell_area_get_margin_top (GtkCellArea *area)
+gtk_cell_area_get_cell_margin_top (GtkCellArea *area)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
- return area->priv->border.top;
+ return area->priv->cell_border.top;
}
void
-gtk_cell_area_set_margin_top (GtkCellArea *area,
- gint margin)
+gtk_cell_area_set_cell_margin_top (GtkCellArea *area,
+ gint margin)
{
GtkCellAreaPrivate *priv;
priv = area->priv;
- if (priv->border.top != margin)
+ if (priv->cell_border.top != margin)
{
- priv->border.top = margin;
+ priv->cell_border.top = margin;
g_object_notify (G_OBJECT (area), "margin-top");
}
}
gint
-gtk_cell_area_get_margin_bottom (GtkCellArea *area)
+gtk_cell_area_get_cell_margin_bottom (GtkCellArea *area)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
- return area->priv->border.bottom;
+ return area->priv->cell_border.bottom;
}
void
-gtk_cell_area_set_margin_bottom (GtkCellArea *area,
- gint margin)
+gtk_cell_area_set_cell_margin_bottom (GtkCellArea *area,
+ gint margin)
{
GtkCellAreaPrivate *priv;
priv = area->priv;
- if (priv->border.bottom != margin)
+ if (priv->cell_border.bottom != margin)
{
- priv->border.bottom = margin;
+ priv->cell_border.bottom = margin;
g_object_notify (G_OBJECT (area), "margin-bottom");
}
/* For convenience in area implementations */
void
-gtk_cell_area_inner_area (GtkCellArea *area,
- GdkRectangle *background_area,
- GdkRectangle *cell_area)
+gtk_cell_area_inner_cell_area (GtkCellArea *area,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area)
{
GtkCellAreaPrivate *priv;
*cell_area = *background_area;
- cell_area->x += priv->border.left;
- cell_area->width -= (priv->border.left + priv->border.right);
- cell_area->y += priv->border.top;
- cell_area->height -= (priv->border.top + priv->border.bottom);
+ cell_area->x += priv->cell_border.left;
+ cell_area->width -= (priv->cell_border.left + priv->cell_border.right);
+ cell_area->y += priv->cell_border.top;
+ cell_area->height -= (priv->cell_border.top + priv->cell_border.bottom);
+}
+
+void
+gtk_cell_area_request_renderer (GtkCellArea *area,
+ GtkCellRenderer *renderer,
+ GtkOrientation orientation,
+ GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkCellAreaPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CELL_AREA (area));
+ g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (minimum_size != NULL);
+ g_return_if_fail (natural_size != NULL);
+
+ priv = area->priv;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (for_size < 0)
+ gtk_cell_renderer_get_preferred_width (renderer, widget, minimum_size, natural_size);
+ else
+ {
+ for_size = MAX (0, for_size - (priv->cell_border.top + priv->cell_border.bottom));
+
+ gtk_cell_renderer_get_preferred_width_for_height (renderer, widget, for_size,
+ minimum_size, natural_size);
+ }
+
+ *minimum_size += (priv->cell_border.left + priv->cell_border.right);
+ *natural_size += (priv->cell_border.left + priv->cell_border.right);
+ }
+ else /* GTK_ORIENTATION_VERTICAL */
+ {
+ if (for_size < 0)
+ gtk_cell_renderer_get_preferred_height (renderer, widget, minimum_size, natural_size);
+ else
+ {
+ for_size = MAX (0, for_size - (priv->cell_border.left + priv->cell_border.right));
+
+ gtk_cell_renderer_get_preferred_height_for_width (renderer, widget, for_size,
+ minimum_size, natural_size);
+ }
+
+ *minimum_size += (priv->cell_border.top + priv->cell_border.bottom);
+ *natural_size += (priv->cell_border.top + priv->cell_border.bottom);
+ }
}
G_OBJECT_WARN_INVALID_PSPEC ((object), "cell property id", (property_id), (pspec))
/* Margins */
-gint gtk_cell_area_get_margin_left (GtkCellArea *area);
-void gtk_cell_area_set_margin_left (GtkCellArea *area,
+gint gtk_cell_area_get_cell_margin_left (GtkCellArea *area);
+void gtk_cell_area_set_cell_margin_left (GtkCellArea *area,
gint margin);
-gint gtk_cell_area_get_margin_right (GtkCellArea *area);
-void gtk_cell_area_set_margin_right (GtkCellArea *area,
+gint gtk_cell_area_get_cell_margin_right (GtkCellArea *area);
+void gtk_cell_area_set_cell_margin_right (GtkCellArea *area,
gint margin);
-gint gtk_cell_area_get_margin_top (GtkCellArea *area);
-void gtk_cell_area_set_margin_top (GtkCellArea *area,
+gint gtk_cell_area_get_cell_margin_top (GtkCellArea *area);
+void gtk_cell_area_set_cell_margin_top (GtkCellArea *area,
gint margin);
-gint gtk_cell_area_get_margin_bottom (GtkCellArea *area);
-void gtk_cell_area_set_margin_bottom (GtkCellArea *area,
+gint gtk_cell_area_get_cell_margin_bottom (GtkCellArea *area);
+void gtk_cell_area_set_cell_margin_bottom (GtkCellArea *area,
gint margin);
-/* For convenience in area implementations */
-void gtk_cell_area_inner_area (GtkCellArea *area,
- GdkRectangle *background_area,
- GdkRectangle *cell_area);
+/* Functions for area implementations */
+
+/* Distinguish the inner cell area from the whole requested area including margins */
+void gtk_cell_area_inner_cell_area (GtkCellArea *area,
+ GdkRectangle *cell_area,
+ GdkRectangle *inner_cell_area);
+
+/* Request the size of a cell while respecting the cell margins (requests are margin inclusive) */
+void gtk_cell_area_request_renderer (GtkCellArea *area,
+ GtkCellRenderer *renderer,
+ GtkOrientation orientation,
+ GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size);
G_END_DECLS
static void init_iter_groups (GtkCellAreaBox *box);
static void init_iter_group (GtkCellAreaBox *box,
GtkCellAreaBoxIter *iter);
-static void get_renderer_size (GtkCellRenderer *renderer,
- GtkOrientation orientation,
- GtkWidget *widget,
- gint for_size,
- gint *minimum_size,
- gint *natural_size);
static GSList *get_allocated_cells (GtkCellAreaBox *box,
GtkCellAreaBoxIter *iter,
GtkWidget *widget);
GtkWidget *widget)
{
const GtkCellAreaBoxAllocation *group_allocs;
+ GtkCellArea *area = GTK_CELL_AREA (box);
GtkCellAreaBoxPrivate *priv = box->priv;
GList *group_list, *cell_list;
GSList *allocated_cells = NULL;
{
CellInfo *info = cell_list->data;
- get_renderer_size (info->renderer,
- priv->orientation,
- widget, -1,
- &sizes[j].minimum_size,
- &sizes[j].natural_size);
+ gtk_cell_area_request_renderer (area, info->renderer,
+ priv->orientation,
+ widget, -1,
+ &sizes[j].minimum_size,
+ &sizes[j].natural_size);
avail_size -= sizes[j].minimum_size;
}
const GdkRectangle *cell_area)
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
+ GtkCellAreaBoxPrivate *priv = box->priv;
GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
GSList *allocated_cells, *l;
+ GdkRectangle background_area, inner_area;
+
+ background_area = *cell_area;
/* Get a list of cells with allocation sizes decided regardless
* of alignments and pack order etc. */
{
AllocatedCell *cell = l->data;
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ background_area.x = cell_area->x + cell->position;
+ background_area.width = cell->size;
+ }
+ else
+ {
+ background_area.y = cell_area->y + cell->position;
+ background_area.height = cell->size;
+ }
+
+ /* Remove margins from the background area to produce the cell area
+ */
+ gtk_cell_area_inner_cell_area (area, &background_area, &inner_area);
+
+ gtk_cell_renderer_render (cell->renderer, cr, widget,
+ &background_area, &inner_area,
+ /* flags */0);
}
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
}
-static void
-get_renderer_size (GtkCellRenderer *renderer,
- GtkOrientation orientation,
- GtkWidget *widget,
- gint for_size,
- gint *minimum_size,
- gint *natural_size)
-{
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- if (for_size < 0)
- gtk_cell_renderer_get_preferred_width (renderer, widget, minimum_size, natural_size);
- else
- gtk_cell_renderer_get_preferred_width_for_height (renderer, widget, for_size,
- minimum_size, natural_size);
- }
- else /* GTK_ORIENTATION_VERTICAL */
- {
- if (for_size < 0)
- gtk_cell_renderer_get_preferred_height (renderer, widget, minimum_size, natural_size);
- else
- gtk_cell_renderer_get_preferred_height_for_width (renderer, widget, for_size,
- minimum_size, natural_size);
- }
-}
-
static void
compute_size (GtkCellAreaBox *box,
GtkOrientation orientation,
gint *natural_size)
{
GtkCellAreaBoxPrivate *priv = box->priv;
+ GtkCellArea *area = GTK_CELL_AREA (box);
CellGroup *group;
CellInfo *info;
GList *cell_list, *group_list;
info = cell_list->data;
- get_renderer_size (info->renderer, orientation, widget, for_size,
- &renderer_min_size, &renderer_nat_size);
+ gtk_cell_area_request_renderer (area, info->renderer, orientation, widget, for_size,
+ &renderer_min_size, &renderer_nat_size);
if (orientation == priv->orientation)
{
}
GtkRequestedSize *
-get_group_sizes (CellGroup *group,
+get_group_sizes (GtkCellArea *area,
+ CellGroup *group,
GtkOrientation orientation,
GtkWidget *widget,
gint *n_sizes)
sizes[i].data = info;
- get_renderer_size (info->renderer,
- orientation, widget, -1,
- &sizes[i].minimum_size,
- &sizes[i].natural_size);
+ gtk_cell_area_request_renderer (area, info->renderer,
+ orientation, widget, -1,
+ &sizes[i].minimum_size,
+ &sizes[i].natural_size);
}
return sizes;
gint *natural_size)
{
GtkCellAreaBoxPrivate *priv = box->priv;
+ GtkCellArea *area = GTK_CELL_AREA (box);
/* Exception for single cell groups */
if (group->n_cells == 1)
{
CellInfo *info = group->cells->data;
- get_renderer_size (info->renderer,
- OPPOSITE_ORIENTATION (priv->orientation),
- widget, for_size, minimum_size, natural_size);
+ gtk_cell_area_request_renderer (area, info->renderer,
+ OPPOSITE_ORIENTATION (priv->orientation),
+ widget, for_size, minimum_size, natural_size);
}
else
{
gint extra_size, extra_extra;
gint min_size = 0, nat_size = 0;
- orientation_sizes = get_group_sizes (group, priv->orientation, widget, &n_sizes);
+ orientation_sizes = get_group_sizes (area, group, priv->orientation, widget, &n_sizes);
/* First naturally allocate the cells in the group into the for_size */
avail_size -= (n_sizes - 1) * priv->spacing;
}
}
- get_renderer_size (info->renderer,
- OPPOSITE_ORIENTATION (priv->orientation),
- widget,
- orientation_sizes[i].minimum_size,
- &cell_min, &cell_nat);
+ gtk_cell_area_request_renderer (area, info->renderer,
+ OPPOSITE_ORIENTATION (priv->orientation),
+ widget,
+ orientation_sizes[i].minimum_size,
+ &cell_min, &cell_nat);
min_size = MAX (min_size, cell_min);
nat_size = MAX (nat_size, cell_nat);